/**
 * 
 */
package truerefactor.output;

import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;

import truerefactor.graph.ClassNode;
import truerefactor.graph.CodeGraph;
import truerefactor.graph.PackageNode;

/**
 * UMLGenerator - A realization of OutputBuilder which uses the Eclipse Modeling
 * Framework to generate a UML Classdiagram from a CodeGraph
 * 
 * @author Isaac Griffith
 */
public class UMLGenerator implements OutputBuilder {

    /**
     * the GraphToUML object which does all the work
     */
    private GraphToUML g2UML;
    /**
     * Graph to be converted
     */
    private CodeGraph graph;
    /**
     * Package Mappings
     */
    private Map<String, EPackage> packageMap;
    /**
     * Class mappings
     */
    private Map<String, EClass> classMap;
    /**
     * list of packages from the graph
     */
    private List<PackageNode> packages;
    /**
     * list of classes from the graph
     */
    private List<ClassNode> classes;
    /**
     * resulting file
     */
    private File results;

    /**
     * Constructs a new UMLGenerator for the provided graph
     * 
     * @param graph
     *            CodeGraph to generate UML for
     */
    public UMLGenerator(CodeGraph graph)
    {
        initialize(graph);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createPackages()
     */
    @Override
    public void createPackages()
    {
        g2UML.createEPackages(packageMap, packages);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createClasses()
     */
    @Override
    public void createClasses()
    {
        g2UML.createEClasses(packageMap, classMap, classes);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createAttributes()
     */
    @Override
    public void createAttributes()
    {
        g2UML.createEAttribues(packageMap, classMap, classes);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createMethods()
     */
    @Override
    public void createMethods()
    {
        g2UML.createEOperations(packageMap, classMap, classes);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createOutputFiles()
     */
    @Override
    public void createOutputFiles(File fileLoc, String comment)
    {
        String writeTo = "";
        String separator = System.getProperty("file.separator");

        if (fileLoc != null && fileLoc.exists() && fileLoc.canWrite())
        {
            writeTo = fileLoc.getPath();
            if (fileLoc.isDirectory())
            {
                if (!writeTo.endsWith(separator))
                {
                    writeTo = writeTo.concat(separator);
                }

                Calendar cal = Calendar.getInstance();
                StringBuilder sb = new StringBuilder(writeTo);
                sb.append("classdiagram_");
                sb.append(cal.get(Calendar.DAY_OF_MONTH));
                sb.append(cal.get(Calendar.MONTH) + 1);
                sb.append(cal.get(Calendar.YEAR));
                sb.append("_");
                sb.append(cal.get(Calendar.HOUR_OF_DAY));
                sb.append(cal.get(Calendar.MINUTE));
                sb.append("_");
                sb.append(comment);
                sb.append(".xmi");
                writeTo = sb.toString();

                System.out.println(writeTo);
            }
        }

        g2UML.generateOutput(writeTo, packageMap, classMap);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#getResult()
     */
    @Override
    public File getResult()
    {
        return results;
    }

    /*
     * (non-Javadoc)
     * @see
     * truerefactor.output.OutputBuilder#setCodeGraph(truerefactor.graph.CodeGraph
     * )
     */
    @Override
    public void setCodeGraph(CodeGraph graph)
    {
        initialize(graph);
    }

    /*
     * (non-Javadoc)
     * @see truerefactor.output.OutputBuilder#createLinksBetweenClasses()
     */
    @Override
    public void createLinksBetweenClasses()
    {
        g2UML.createClassHierarchy(classMap, classes);
    }

    /**
     * Inializes this UMLGenerator for use with the provided codegraph
     * 
     * @param graph
     *            graph to generate UML for
     */
    private void initialize(CodeGraph graph)
    {
        this.graph = graph;
        g2UML = new GraphToUML();
        packageMap = new HashMap<String, EPackage>();
        classMap = new HashMap<String, EClass>();

        classes = graph.getClasses();
        packages = graph.getPackages();
    }
}
